
import pygame
import math
import sys

"""
Interface for BoardGame
"""

pygame.init() 

class Game:
	MODE_INIT = 0
	MODE_PLAY = 1
	MODE_RESULT = 2

	def __init__ (self):
		self.board = None
		self.gamemode = Game.MODE_INIT

	def startPlay (self):
		while 1:
			for event in pygame.event.get():
				self.handleEvent(event)
				if (hasattr(self.board,"beforeEvent")):
					self.board.beforeEvent(event)
				if (hasattr(self.board,"handleEvent")):
					self.board.handleEvent(event)
				if (hasattr(self.board,"afterEvent")):
					self.board.afterEvent(event)
			pygame.time.wait(50)
		pass
	
	def handleEvent (self, event):
		if event.type == pygame.QUIT: 
			sys.exit()
		pass


class MyGame (Game):
	def handleEvent (self, event):
		if event.type == pygame.QUIT: 
			print "handling event\n"
			sys.exit()
		pass


class Board:
	def __init__(self) :
		pass

	def do (self, move):
		"""
		Given a move, applies it to current board which may result in change in board state.
		"""
		pass

	def undo (self, move):
		"""
		Given a move, reverse apply it to current board to result in previous state.
		"""
		pass

	def addPlayer (self, player):
		"""
		Add a player to current board.
		"""
		pass

	def removePlayer (self, player):
		"""
		Removes a player from current board.
		"""
		pass

	def paint (self) :
		pass


class GridBoard (Board):

	def __init__ (self, row=0, col=0) :
		Board.__init__(self)
		self.rows = row 
		self.cols = col 
		self.margin = 5 
		self.fgcolor = 200, 200, 200
		self.bgcolor = 0, 0, 0
		self.bgimage = None
		self.gridimage = None
		self.gridon = True
		self.gridwidth = 1
		self.width = 320
		self.height = 240
		self.topMargin = 20 
		self.bottomMargin = 20 
		self.leftMargin = 20 
		self.rightMargin = 20 
		self.totalWidth = self.width - self.leftMargin - self.rightMargin
		self.totalHeight = self.height - self.topMargin - self.bottomMargin
		self.selectedGroups = {}
		self.initBoardState()

		self.isgp2x = False
		if "arm" in sys.version:
			self.isgp2x = True

		if self.isgp2x :
			self.screen = pygame.display.set_mode ( (self.width, self.height), pygame.FULLSCREEN)
		else :
			self.screen = pygame.display.set_mode ( (self.width, self.height), pygame.RESIZABLE)

		num_joysticks = pygame.joystick.get_count()
		if num_joysticks > 0:
			stick = pygame.joystick.Joystick(0)
			stick.init() # now we will receive events for the joystick

		self.paint()

	def initBoardState (self) :
		self.boardState = []
		for row in range(self.rows):
			self.boardState.append([])
			self.boardState[-1] = []
			for col in range (self.cols):
				self.boardState[-1].append(None)

	def setCellState (self, state, row, col) :
		self.boardState[int(row)][int(col)] = state

	def getCellState (self, row, col) :
		return self.boardState [int(row)][int(col)]

	def paint (self) :
		self.width = self.screen.get_width()
		self.height = self.screen.get_height()
		self.screen.fill (self.bgcolor) 
		#Draw background image
		if (self.bgimage != None):
			img = pygame.transform.scale(self.bgimage, (self.width, self.height)) 
			self.screen.blit (img, (0,0))
			pass

		self.totalWidth = self.width - self.leftMargin - self.rightMargin
		self.totalHeight = self.height - self.topMargin - self.bottomMargin

		#Draw grid image
		if (self.gridimage != None):
			img = pygame.transform.scale(self.gridimage, (self.totalWidth, self.totalHeight)) 
			self.screen.blit (img, (self.leftMargin, self.topMargin))


		for row in range(self.rows):
			for col in range(self.cols):
				if (hasattr(self,"getCellBgColor")):
					cellcolor = self.getCellBgColor(row, col)
					pygame.draw.rect(self.screen, cellcolor, (self.getX(col), self.getY(row), self.getX(col + 1) - self.getX(col), self.getY(row + 1) - self.getY(row)), 0)
				if (hasattr(self,"getCellBgImage")):
					cellimg = self.getCellBgImage(row, col)
					if cellimg != None:
						img = pygame.transform.scale(cellimg, (self.totalWidth/self.cols, self.totalHeight/self.rows))
						self.screen.blit (img, (self.leftMargin + (self.totalWidth*col/self.cols), self.topMargin + (self.totalHeight*row/self.rows)))
				if (hasattr(self,"getCellImage")):
					cellimg = self.getCellImage(row, col)
					if cellimg != None:
						img = pygame.transform.scale(cellimg, (self.totalWidth/self.cols, self.totalHeight/self.rows))
						self.screen.blit (img, (self.leftMargin + (self.totalWidth*col/self.cols), self.topMargin + (self.totalHeight*row/self.rows)))

		#Draw grid
		if (self.gridon):
			pygame.draw.rect(self.screen, self.fgcolor, (self.leftMargin, self.topMargin, self.totalWidth, self.totalHeight), self.gridwidth)
			for i in range(self.rows - 1):
				pygame.draw.line(self.screen, self.fgcolor, (self.getX(0), self.getY(i+1)) , (self.leftMargin + self.totalWidth - 1, self.getY(i+1)), self.gridwidth)
				pass

			for i in range(self.cols - 1):
				pygame.draw.line(self.screen, self.fgcolor, (self.getX(i+1), self.getY(0)) , (self.getX(i+1), self.topMargin + self.totalHeight - 1 ), self.gridwidth)
				pass

		for group in self.selectedGroups.keys():
			list = self.selectedGroups[group]
			for pos in list:
				row, col = pos
				borderColor = self.getSelectedGroupColor (group)
				pygame.draw.rect (self.screen, borderColor, (self.getX(col), self.getY(row), self.getX(col+1) - self.getX(col) + 1, self.getY(row+1) - self.getY(row) + 1), 2)
				
		pygame.display.flip()
		pass

	def getX (self, col):
		return self.leftMargin + (self.totalWidth*col)/self.cols

	def getY (self, row):
		return self.topMargin + (self.totalHeight*row)/self.rows

	def getCell (self, x, y):
		if (x < self.leftMargin or x > self.leftMargin + self.totalWidth or y < self.topMargin or y > self.topMargin + self.totalHeight) :
			return None 

		cellWidth = self.totalWidth / self.cols
		cellHeight = self.totalHeight / self.rows

		return [ math.floor ( (y - self.topMargin) * self.rows/ self.totalHeight), math.floor( (x - self.leftMargin) * self.cols / self.totalWidth)] 

	def addCellToSelectedGroup (self, groupname, row, col):
		if (groupname in self.selectedGroups):
			list = self.selectedGroups[groupname]
		else :
			list = []
			self.selectedGroups[groupname] = list
		if (groupname.startswith("ex-")) :
			del list[:]
		list.append ( [row, col] )

	def removeCellFromSelectedGroup (self, groupname, row, col):
		list = self.selectedGroups[groupname]
		if (list == None):
			return
		list.remove ( [row, col] )

	def toggleCellInSelectedGroup (self, groupname, row, col):
		if (self.isCellInSelectedGroup (groupname, row, col)):
			self.removeCellFromSelectedGroup (groupname, row, col)
		else :
			self.addCellToSelectedGroup (groupname, row, col)

	def isCellInSelectedGroup (self, groupname, row, col):
		if (groupname in self.selectedGroups):
			list = self.selectedGroups[groupname]
		else :
			return False 
		return [row, col] in list 

	def getSelectedGroupColor (self, groupname):
		return (200, 0, 0)


	def getDiagonals (self, row, col):
		pass

	def leftClickCell(self, row, col) :
		print str(row) + " " + str(col)
		pass
	
	def rightClickCell(self, row, col) :
		print str(row) + " " + str(col)
		pass

	def keyHit (self, key) :
		pass

	def handleEvent (self, event):
		if event.type == pygame.VIDEORESIZE: 
			self.screen = pygame.display.set_mode ( (event.w, event.h), pygame.RESIZABLE)
			self.paint() 	

		if event.type == pygame.MOUSEBUTTONDOWN: 
			print event.button
			(x, y) = event.pos
			cell = self.getCell (x,y)	
			if (cell != None):
				(row, col) = cell
				if (event.button == 1):
					self.leftClickCell(row, col) 	

				if (event.button == 3):
					self.rightClickCell(row, col) 	

		if event.type == pygame.JOYAXISMOTION:
			sys.exit()

		pass


"""
Interface for a Move which can be applied on a board.
"""

class Move :
	def __init__ (self) :
		self.player = None
		self.data = None

	def getPlayer (self) :
		return self.player

	def setPlayer (self, player) :
		self.player = player

	def getData (self) :
		return self.data

	def setData (self, data) :
		self.data = data


class Player :
	def __init__ (self) :
		self.playerdata = None
		pass

	def getPlayerData (self) :
		return self.playerdata 

	def setPlayerData (self, playerdata) :
		self.playerdata = playerdata

